package zapx

import (
	"time"

	"gitee.com/chewel/hermes/pkg/journal"
	"go.uber.org/zap"
)

type ZapLogger struct {
	l *zap.Logger
}

func (z *ZapLogger) With(fields ...journal.Field) journal.ILogger {
	z.l.With(z.zapFields(fields)...)
	return z
}

func (z *ZapLogger) Debug(msg string, fields ...journal.Field) {
	z.l.Debug(msg, z.zapFields(fields)...)
}

func (z *ZapLogger) Info(msg string, fields ...journal.Field) {
	z.l.Info(msg, z.zapFields(fields)...)
}

func (z *ZapLogger) Warn(msg string, fields ...journal.Field) {
	z.l.Warn(msg, z.zapFields(fields)...)
}

func (z *ZapLogger) Error(msg string, fields ...journal.Field) {
	z.l.Error(msg, z.zapFields(fields)...)
}

func (z *ZapLogger) Fatal(msg string, fields ...journal.Field) {
	z.l.Fatal(msg, z.zapFields(fields)...)
}

func (z *ZapLogger) Panic(msg string, fields ...journal.Field) {
	z.l.Panic(msg, z.zapFields(fields)...)
}

func (z *ZapLogger) zapFields(fields []journal.Field) []zap.Field {
	zapFields := make([]zap.Field, 0, len(fields))
	for _, field := range fields {
		switch field.Type {
		case journal.FieldTypeString:
			zapFields = append(zapFields, zap.String(field.Key, field.Value.(string)))
		case journal.FieldTypeInt:
			zapFields = append(zapFields, zap.Int(field.Key, field.Value.(int)))
		case journal.FieldTypeInt8:
			zapFields = append(zapFields, zap.Int8(field.Key, field.Value.(int8)))
		case journal.FieldTypeUnknown:
			zapFields = append(zapFields, zap.Any(field.Key, field.Value))
		case journal.FieldTypeInt16:
			zapFields = append(zapFields, zap.Int16(field.Key, field.Value.(int16)))
		case journal.FieldTypeBoolean:
			zapFields = append(zapFields, zap.Bool(field.Key, field.Value.(bool)))
		case journal.FieldTypeInt32:
			zapFields = append(zapFields, zap.Int32(field.Key, field.Value.(int32)))
		case journal.FieldTypeInt64:
			zapFields = append(zapFields, zap.Int64(field.Key, field.Value.(int64)))
		case journal.FieldTypeFloat32:
			zapFields = append(zapFields, zap.Float32(field.Key, field.Value.(float32)))
		case journal.FieldTypeFloat64:
			zapFields = append(zapFields, zap.Float64(field.Key, field.Value.(float64)))
		case journal.FieldTypeTime:
			zapFields = append(zapFields, zap.Time(field.Key, field.Value.(time.Time)))
		case journal.FieldTypeDuration:
			zapFields = append(zapFields, zap.Duration(field.Key, field.Value.(time.Duration)))
		case journal.FieldTypeError:
			zapFields = append(zapFields, zap.Error(field.Value.(error)))
		default:
			zapFields = append(zapFields, zap.Any(field.Key, field.Value))
		}
	}
	return zapFields
}

func NewLogger(logger *zap.Logger) journal.ILogger {
	return &ZapLogger{
		l: logger,
	}
}
